import time
from sklearn.model_selection import train_test_split
from lazypredict.Supervised import LazyClassifier
from tabulate import tabulate
import logging
import numpy as np
import gradio as gr
import cv2
import faiss
from util import createXY
import joblib


# 配置logging, 确保能够打印正在运行的函数名
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 数据加载和预处理
X, y = createXY(train_folder="data/train", dest_folder=".",method='flat')
X = np.array(X).astype('float32')
faiss.normalize_L2(X)  # 对数据进行L2归一化
y = np.array(y)
logging.info("数据加载和预处理完成。")

# 数据集分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=2023)
logging.info("数据集划分为训练集和测试集。")

clf = LazyClassifier()
result, _ = clf.fit(X_train, X_test, y_train, y_test)
print(result)

# 获取F1分数最高的模型
best_model_name = result['F1 Score'].idxmax()  # 获取F1分数最高行的索引值，即：模型名称
print("\nF1分数最高的模型是: ", best_model_name)

# clf.models 是包含所有训练过的模型 (名称, 模型对象) 键值对的字典
best_model = clf.models[best_model_name]  # 根据模型名称，从模型字典中获取模型对象

result = best_model.predict(X_test)  # 该字典可以直接被拿来进行预测
print(f"用{best_model_name}预测X_test的结果是:\n{result}")
# 保存准确率最高的模型
joblib.dump(best_model, 'best_model.pkl')
#加载模型
best_model=joblib.load('best_model.pkl')
# Gradio界面函数
# def classify_image(image):
#     img = cv2.imdecode(np.fromstring(image.read(), np.uint8), cv2.IMREAD_COLOR)
#     img = cv2.resize(img, (224, 224))
#     img = img.reshape(1, -1).astype('float32')
#     faiss.normalize_L2(img)

#     prediction = best_model.predict(img)
#     return "狗" if prediction[0] == 0 else "猫"
def classify_image(image):
    img = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)   #将图像从BGR格式转换为RGB格式
    img = cv2.resize(img, (32, 32))   #将图像调整为32x32
    img = img.reshape(1, -1)   #将图像展平
    prediction = best_model.predict(img)   #预测图像的标签
    return '猫' if prediction[0]==1 else '狗'   #返回预测结果

# 创建Gradio界面
iface = gr.Interface(fn=classify_image, inputs="image", outputs="text")
iface.launch()